package sfeir.ergosum.tools;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.security.NoSuchAlgorithmException;

import sfeir.ergosum.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.EmbossMaskFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.provider.Contacts.People;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;

public class CachedImageView extends ImageView {

    Bitmap b;

    public CachedImageView(Context context) {
        super(context);
    }

    public CachedImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CachedImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (b != null) {
            Paint p = new Paint();
            EmbossMaskFilter emf = new EmbossMaskFilter(
                    new float[] { 1, 1, 1 }, 0.4f, 6, 3.5f);

            p.setMaskFilter(emf);
            canvas.drawBitmap(b, 0, 0, p);
        }
        canvas.restore();
    }

    public void generatedImageFromUrl(String url) {

        setImageResource(R.drawable.person_large);

        if (url != null) {

            final String fUrl = url;
            Thread imgThread = new Thread() {
                public void run() {

                    String md5 = md5(fUrl);
                    try {
                        FileInputStream fis = getContext().openFileInput(md5);
                        b = BitmapFactory.decodeStream(fis);
                        fis.close();

                    } catch (FileNotFoundException e) {
                        try {
                            Bitmap getB;
                            if (!fUrl.startsWith("content:")) {
                                getB = getImageBitmap(fUrl, 80);
                                if (getB != null) {
                                    b = getB;
                                    FileOutputStream fos = getContext()
                                            .openFileOutput(md5, 0);
                                    b.compress(CompressFormat.PNG, 100, fos);
                                    fos.close();
                                }
                            } else {
                                getB = People.loadContactPhoto(getContext(),
                                        Uri.parse(fUrl),
                                        R.drawable.person_large, null);
                                if (getB.getWidth() > 80) {
                                    getB = resizeBitmap(getB, 80);
                                }
                                b = getB;
                            }
                        } catch (FileNotFoundException e1) {
                            e1.printStackTrace();
                        } catch (IOException e2) {
                            e2.printStackTrace();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            };
            imgThread.start();

        }

    }

    public static String md5(String url) {
        String result = "";
        java.security.MessageDigest msgDigest;
        try {
            msgDigest = java.security.MessageDigest.getInstance("MD5");

            msgDigest.update(url.getBytes());
            byte[] digest = msgDigest.digest();
            for (int i = 0; i < digest.length; ++i) {
                int value = digest[i];
                if (value < 0) {
                    value += 256;
                }
                result += Integer.toHexString(value);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static Bitmap getImageBitmap(String url, int size) {
        Bitmap bm = null;
        Bitmap resizedBm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();

            BufferedInputStream bis = new BufferedInputStream(is);

            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();

            if (bm != null) {
                int width = bm.getWidth();
                int height = bm.getHeight();
                int newWidth = size;
                int newHeight = size;

                // calculate the scale - in this case = 0.4f
                float scaleWidth = ((float) newWidth) / width;
                float scaleHeight = ((float) newHeight) / height;

                float maxScale = Math.max(scaleWidth, scaleHeight);

                // createa matrix for the manipulation
                Matrix matrix = new Matrix();
                // resize the bit map
                matrix.postScale(maxScale, maxScale);

                // rotate the Bitmap
                // matrix.postRotate(45);

                int minSize = Math.min(width, height);
                // recreate the new Bitmap
                resizedBm = Bitmap.createBitmap(bm, 0, 0, minSize, minSize,
                        matrix, true);
            } else
                resizedBm = null;

        } catch (IOException e) {
            return null;
        }

        return resizedBm;
    }

    public static Bitmap resizeBitmap(Bitmap b, int size) {

        if (null == b) {
            Log.e(CachedImageView.class.getName(),
                    "resizeBitmap : input bitmap shouldn’t be null");
            return null;
        }
        Bitmap resizedBm = null;

        int width = b.getWidth();
        int height = b.getHeight();
        int newWidth = size;
        int newHeight = size;

        // calculate the scale - in this case = 0.4f
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;

        float maxScale = Math.max(scaleWidth, scaleHeight);

        // createa matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the bit map
        matrix.postScale(maxScale, maxScale);

        // rotate the Bitmap
        // matrix.postRotate(45);

        int minSize = Math.min(width, height);
        // recreate the new Bitmap
        resizedBm = Bitmap
                .createBitmap(b, 0, 0, minSize, minSize, matrix, true);

        return resizedBm;
    }
}
